UNIX MAGAZINE 2001年2月号

キーフレーズ

UNIX MAGAZINE VMware Linux http:// Windows ファイル NetBSD RFC www サーバー ネットワーク 2001 システム vmware インターネット Web インストール 2000 ファイルシステム CD-ROM OSPF ルータ 場合 利用 ディレクトリ JavaScript クライアント html 000 for NFA 接続 設定 FreeBSD 機能 CVS co.jp linux インターフェイス CPU total モジュール DNS Windows 2000 本体価格 -3 アプリケーション 必要 対応 サービス cvs state .com 実行 指定 -1 できる finalst プログラム コマンド Subject ftp QoS プロバイダ コンピュータ モード () データ Ethernet usr int Newsgroups SOHO 処理 表示 IETF ペイロード LAN Base Sun research 情報 管理 可能 Java this アクセス WWW RTP CFILE link org lnternet tools ディスク Configuration RAID text NAME

目次

Java Advisor 丘 om Performance Computing David Detlefs 気分転換のための計算 コンピュータのプログラミングで生計を立てているにも かかわらす、迎未のプログラムを書きたいという彳力に駆 られたことはないだろうか。私の場合は、この発イ勧起き たらあまり逆らわないようにしている。クラシックのピア ニストがジャズのリフをかき鳴らしてみるように、気晴ら しに何か違ったことをするのはよいことだ。まったく関係 のなさそうなプログラムの開発から、あとで役に立っスキ ルを得ることも多い ( もちろん、研究という気楽な仕事を していて、プロジェクトの期限とはほとんど縁のない不劫ゞ いうのもおこがましいか ) 。 私の蜷丘の気晴らしのきっかけは、同僚の Anne An- derson か私たちのグループにメールである問題を送って きたことだった。間題とは以下のようなものである。 に、すこし壊れていて数字キーが、、 1 " しか使えない電卓が ある。この電卓でキーを 20 回以 E 打たすに、、 75 " を表示 できるだろうか。なお、電卓には十、 十という 4 構造化すべきなのだろうか。ます、 18 回以下のキー入力 のシーケンスをすべて洗い出し、それが 75 を導くかどう か試すというガ去がある。電卓には使えるキーが 8 つある ので、長さが 18 のシーケンスは 818 、つまり 254 個ある ことになる ( 18 より短いものはまだ含まれていない ) 。最 近のコンピュータは速くなったが、それでもこれを言 1 算す るには時憫がかかるだろう。 したがって、もうすこし工夫が必要である。これはそれ ほど難しいことではない。さきほどのシーケンスに、演算 キーと瓜だけの、数字をまったく含まないものが 718 個 あることに気づけばよいのだ。未のある数値を求められ る有効な文字列だけを選べば、、、無駄な " シーケンスの大 半を除外することができる。 有効な文字列の部分集合を定義する場合、文法は効果的 な手段である ( 部分集合は、言語内では文去によって定義 される ) 。そこで、私は電卓言語のための文法を作ってみ た。以下に示すのカ撮初に作ったものである ( プログラム 言語の去を定義する際に使われるバッカス記去 (BNF: Backus-Naur Form) で言己してある ) 。 つの基べ寅算キーと、 、開き括弧閉し括弧のキーがあ る。ー・縞 ; の電卓とは異なり、れ * = はれの 2 乗にならない。 電卓を手にあれこれ試してみると、 19 回のキー入力で 答を得るのはそれほど難しいことではなく、実際にほとん どの挑戦者が成功した。その一方で、これより少ないキー 入力で答を出せた者はいなかった。しかし、はたしてそれ か不可能なのか誰にも分からす、何人かは間的に可能な はずだと考えた。興未を抱いた私は、総当たり的な検索で 答をみつけだすプログラムを書いてみることにした。今回 は、このプログラムの開発過程を、間違いや行き詰まった 点 ( の一縞分も含めて紹介する。 プログラムを趣床て書いている場合でも、すこし秩序だ てて考えてみれは効率的である。最初のステップとなるべ きなのは問題の分析だ。総当たり的な検索とはどのように UNIX MAGAZINE 2001.2 Term ParenTerm ー BinaryTerm ー Equa1Term ー Numb e r B inaryTe rm , ( , Term Term ) 十 ) ー Term ー Term , / , Equa1Term Number : : = ) 1 ' ー Number Term Term , 1 ' 分析用の道具としてみると、文法にはプログラム ( すく 113

int i, init, state_offset ; int state = int last = lastst Cmach] ; 必要な変数を宣言したあと、変数 last を、 NFA を表 すために用いる添え囎物 ) なかでもっとも大きな値である lastst[mach] にしています。 次は、 firstst [mach] から上で計算した last までの for ループです。 firstst [mach] は NFA を表すために用いる 添え字君 ) なかでもっとも小さな値ですか、この硼を 調べればかならず NFA 本を謌・ヾることになります。 for ( i firstst [mach] ; i く = 1ast ; 十十 i ) こでおこなわれる処理は重要ですが、実際の処理をみ ると思ったより叫屯です。新たな状態を作成しますが、そ のとき遷移のラベルとしてはもとの状態に対応するものを コピーします。 state = mkstate( transchar[i] ) ; さらに、そこから遷移がある (transl が NO-TRAN- SITION ではない ) 場合は、その遷移を新たな状態からも 作成します。ただし、遷移先としては transl[i] 十 state—i を使います。この式は、、、 1 番から 5 番にコピーしている のであれば、遷移先が 2 番ならコピー先では 6 番に遷移 したらよいだろう " という意味です。 if ( transl [i] ! = NO—TRANSITION ) mkxtion( finalst [state] , , ・ transl [i] + state if ( transchar[i] = SYM_EPSILON & & trans2 [i] ! = NO—TRANSITION ) mkxtion( finalst Cstate] , trans2[i] 十 state accptnum [state] accptnum [i] ; trans2 についても同様に処理したあと、 accptnum を 調整してループを終了します。 驚いたことに、この関数では実際にその番号が必要かど うかはまったく関係なく、最小の値から最大の値まで、す べてをコピーしています。たしかにこれなら、 NFA に関 連するものはコピーすることかて、きます。本当にこれでよ いのか考えてみましたが、構文角 i 器での角財斤と並行して NFA を構築しているため、処理の対象はつねにいま見て 112 いる点よりもほんのすこし前のものとなっています。ま た、連結や選択をおこなう場合も、あいだにまったく無 関係な NFA が入ってくることはないため、このような簡 単なコピーガ去でも大丈夫です。万一よけいな情報までコ ピーしていたとしても、その部分は利用されす、メモリを 自するという点を除けばとくに問題はありません。 最後に、 firstst 、 finalst 、 lastst のイ直をイ正し、 init の flexfatal ( if ( state = = 値を返せば NFA のコピーは完了です。 dupmachine ( ) ” ー ( "empty machine in = init = mach 十 firstst [init] finalst [init] lastst [init] state_offset return ; state lastst [mach] 十 state—offset; finalst [mach] + state—offset ; firstst [mach] 十 state—offset ; state_offset ; 無駄な領域はすべて除いて本をコピーするにちがいな いと思いこんでいただけに、この角夬方法はすこし意汐トで ☆ 今回は flex コマンドが入力中の正規表現を NFA に変 換する部分について解説しました。 flex では、複数の酉改」 を使って NFA を表現しています。また、 NFA に必要な 領域をできるだけ分散させないようにする手法を用いて、 簡単な NFA のコピーを実現しています。 次回は、今回作成した NFA を処理して最終的に DFA を入手する過程をみていく予定です。 ( たしみ・ひさかす ) UNIX MAGAZINE 2001.2

図 7 ポインタを用いたデータ橢告 NO typedef struct struct int } state; typedef struct struct int struct } trans; NO state trans trans trans state YES trans ; accept ; next ; transchar ・ dest ; ASCII 好評発売中 ! Java フログラミング・ノート 国際化と 日本語処理 CAFE BABE 0 製ー X 国際化と日本語処理 ( A ド第第 A ・第 プログラミング・ノート ava ・本体 3 , 000 円十税 ・ ISBN 4-7561-3481-5 ・ A5 判、 312 ページ ・風間一洋著 Run Anywhere" を目指すプログラマー 解説する。真の意味での "write Once, サンプル・プログラムを示しながら平易に プログラミングに必須の知識を数多くの Java による日本語処理、さらには国際化 目次から に最適の 1 冊。 これは、 NFA を操作するにはその頁およひ末尾の状 態を操作すればよいという点に注目し、さらに状態や遷移 をそのまま構造体にマッピングしたものです。このデータ 構造を使って図 4 の NFA を表現したのか図 7 です。 このようなデータ構造を使用する場合、 NFA のコピー は不可能ではありませんが、ひどく面倒になります。たと えは、右端のノードは 2 つのポインタに指されています が、ノードをコピーしている最中につねに 2 つのノード か伺しかどうかを調べながら処理しないと、このようなノ ードでも別のノードとしてコピーしてしまうことになりま す。また、 こで作成した NFA には区しがありませ んが、一殳には NFA の前のほうに戻る遷移も多くありま す。これらをすべて正しく処理するのは、無理ではないに しろかなり面倒です。 一方、 flex では基本的にメモリ領域のコピーだけで NFA のコピーができるようになっています。この処理を おこなうのが nfa. c ファイルで定義されている dupma- chine 関数です。それでは、この関数をみていきましよう。 引数は、コピーしたい NFA を表す整数のみです。 int dupmachine ( mach ) int mach; UNIX MAGAZINE 2001.2 1 章 2 章 3 章 4 章 5 章 6 章 7 章 8 章 9 章 10 章 1 1 章 12 章 付録 Java はどんな言語か 国際化と地域化 Unicode ロケー丿レ 工ンコーティング タイムゾーン リソースパンドル フォーマット出力と解析 文字列の比較 テキストの境界解析 インブットメソッド 文字の表示 Unicode プロック / ロケール一覧 / 工ンコーディング名一覧 / タイムゾーン D 一覧 / ユーロ通貨記号への対応 株式会社アスキー 111 電話 (08) 535 ト 8194 出版営業部 〒 1 5 1 ー 8024 東京都渋谷区代々木 4 ー 33 ー 1 0